//#include "include/Arcroll.h"
//#define Matrix4x4 Viewer_Matrix4x4_
#include<stdio.h>
#include<Viewer_Interpreter/Viewer_OpenGL_Interpreter.h>
#include<Arcroll.h>
//#include<Mesh_IO/Mesh_IO.h>

#include<tool/libcell_tools_view.h>
#include <tool/tools_formats.h>
#include<points_cloud_algorithm.h>
#include<zkhy_tools/zkhy_tools_common.h>
#define Matrix4x4 Viewer_Matrix4x4_

#define quote lib_cell_quote

void set_default_voi(Viewer_Opengl_Interpreter* voi,Viewer_World*vw)
{

    //Viewer_World_Manager* vwm=(Viewer_World_Manager*)malloc(sizeof(Viewer_World_Manager));
     
    char camera[]="Camera";
    Node* n=vw->create_something(vw,camera);
    Viewer_Something*ms=(Viewer_Something*)(n->value);
    Viewer_Camera*mc=(Viewer_Camera*)(ms->evolution);
    mc->is_using=1;
    Matrix4x4 *p=Projection(M_PI/3.0f,(float)(vw->g_info->resolution[0])/(float)(vw->g_info->resolution[1]),0.5f,200.0f);
    p->copy_data(mc->Proj,p);
    Matrix4x4_free(p);

    free_node(n);

    char edges[]="Edges";
//**********************************

    n=vw->create_something(vw,edges);
    auto vs=(Viewer_Something*)(n->value);
  //  vs->disappear=1;
    auto ve=(Viewer_Edges*)(vs->evolution);
    ve->Data_rows=4;
    ve->Data_index_rows=3;
    ve->Data=(float*)malloc(sizeof(float)*3*ve->Data_rows);
    ve->Data_index=(unsigned int*)malloc(sizeof(unsigned int)*2*ve->Data_index_rows);     
    ve->Data[0]=0;ve->Data[1]=0;ve->Data[2]=0;
    ve->Data[3]=1;ve->Data[4]=0;ve->Data[5]=0;
    ve->Data[6]=0;ve->Data[7]=1;ve->Data[8]=0; 
    ve->Data[9]=0;ve->Data[10]=0;ve->Data[11]=1;
   

    ve->Data_index[0]=0;ve->Data_index[1]=1;
    ve->Data_index[2]=0;ve->Data_index[3]=2; 
    ve->Data_index[4]=0;ve->Data_index[5]=3;


    ve->color_rows=ve->Data_index_rows;
    ve->color=(float*)malloc(sizeof(float)*4*ve->color_rows);
    memset(ve->color,0,sizeof(float)*4*ve->color_rows);

    ve->color[0]=1;ve->color[1]=0; ve->color[2]=0;ve->color[3]=1;
    ve->color[4]=0;ve->color[5]=1; ve->color[6]=0;ve->color[7]=1;
    ve->color[8]=0;ve->color[9]=0; ve->color[10]=1;ve->color[11]=1;
    free_node(n); 
//********//
    Viewer_Arcroll*ma=(Viewer_Arcroll*)malloc(sizeof(Viewer_Arcroll));
    Viewer_Arcroll_init(ma);
    ma->mc=mc;
    ma->vw=vw;
    ma->voi=voi;
    
    ma->vs=vs;
//****//
    char intera[]="Intera";
    n=vw->create_something(vw,intera);
    ms=(Viewer_Something*)(n->value);

    Viewer_Intera* mi=(Viewer_Intera*)(ms->evolution);
    mi->representation=(void*)ma;
    mi->cursor_position_callback=viewer_Arcroll_cursor_position_callback;
    mi->scroll_callback=viewer_Arcroll_scroll_callback;
    mi->mouse_button_callback=viewer_Arcroll_mouse_button_callback;
   // mi->drop_callback=viewer_Arcroll_drop_callback;
    mi->key_callback=viewer_Arcroll_key_callback;
    free_node(n);

}
void test_denoising()
{
    Mesh mesh;
    Mesh_init(&mesh);
    char file[]="0831.obj";
    _Read_(&mesh,file);
    std::map<int,int> mp1;std::map<int,Node*> mp2;

    Mesh* mesh1=points_cloud_simplify_points_from_mesh(&mesh,10,mp1,mp2);

    printf("numv:%d\n",mesh1->num_v(mesh1) );
    Points_Cloud_Analyzer* pca=points_cloud_analyze_points_from_mesh(mesh1);
    //printf("%lf\n",pca->median_distance );
    Node* node = points_cloud_classify_points_from_mesh(mesh1,1.5*pca->median_distance);
    printf("node_size:%d\n",node_size(node) );
    int size=0;double que=mesh1->num_v(mesh1)*2.0/100.0;
    for(Node* nit=node;nit!=NULL;nit=(Node*)(nit->Next))
    {
        size=node_size((Node*)(nit->value));
        if(size<que)
        {
            for(Node* nnit=(Node*)(nit->value);nnit!=NULL;nnit=(Node*)(nnit->Next))
            {
                template_v*v=(template_v*)(nnit->value);
                mesh1->delete_vertex(mesh1,*v,true);
            }
        } 
        printf("%d %lf\n",size,que );
        //printf("node node_size:%d\n",node_size((Node*)(nit->value)));
    }
    printf("%d %d\n",mesh1->num_v(mesh1),mp2.size() );


    char filename[]="denosing.obj";
#ifdef _WIN32
    FILE *infile;
    fopen_s(&infile,filename,"w");
#else
    FILE *infile=fopen(filename,"w");
#endif
    for(auto it=mesh1->v_begin(mesh1);it!=mesh1->v_end(mesh1);it++)
    {
        template_v* v=quote(it),*v1=NULL;
        Node* n=mp2[v->id];
        for(Node*nit =n;nit!=NULL;nit=(Node*)(nit->Next))
        {
            v=(template_v*)(nit->value);
            fprintf(infile, "v %lf %lf %lf\n",v->point[0],v->point[1],v->point[2]);
        }
    } 
    fclose(infile);
    // Viewer_World_Manager* vwm=(Viewer_World_Manager*)malloc(sizeof(Viewer_World_Manager));
    // viewer_world_manager_init(vwm);
    // Viewer_World *vw=vwm->create_world(vwm,NULL);
    

    // Viewer_Opengl_Interpreter *voi=(Viewer_Opengl_Interpreter*)malloc(sizeof(Viewer_Opengl_Interpreter));
    // viewer_opengl_interpreter_initn(voi,vwm);
  
    
    // char points[]="Points";
    // Node* n=vw->create_something(vw,points);
    // auto vs=(Viewer_Something*)(n->value);
    // auto vp=(Viewer_Points*)(vs->evolution);
    // vp->Data_rows= mesh1->num_v(mesh1);
  
    // vp->pointsize=5.0;
    // vp->Data=(float*)malloc(sizeof(float)*3*vp->Data_rows);
    // int i=0;
    // for(auto vit=Mesh_v_begin(mesh1);vit!=Mesh_v_end(mesh1);vit++)
    // {
    //     vp->Data[i]=((template_v*)(vit.second))->point[0];
    //     i++;
    //     vp->Data[i]=((template_v*)(vit.second))->point[1];
    //     i++;
    //     vp->Data[i]=((template_v*)(vit.second))->point[2];
    //     i++;
    // }
    // float color[4]={0.9,0.2,0.5,1.0};
    // vp->set_color(vp,color);
    // set_default_voi(voi,vw);
    // voi->interpreter(voi);
    Mesh_free(&mesh);Mesh_free(mesh1);free(mesh1);
    printf("test noising end\n");
}


void test_viewer()
{

    Viewer_World_Manager *vwm=(Viewer_World_Manager*)malloc(sizeof(Viewer_World_Manager));
    viewer_world_manager_init(vwm);

    Viewer_World *vw=vwm->create_world(vwm,NULL);

   
    Viewer_Opengl_Interpreter *voi=(Viewer_Opengl_Interpreter*)malloc(sizeof(Viewer_Opengl_Interpreter));
    viewer_opengl_interpreter_initn(voi,vwm);

    voi->interpreter(voi);
}

int main()
{
    test_denoising(); 
    return 1;
}
